from pylons import g,request,c
import pyleo.model.wikiBNL.formatter as wikiBNL
import pyleo.model.wiki04.formatter as wiki04
import pyleo.model.xhtml.formatter as xhtml
import pyleo.model.blogcalendar as BC
from pyleo.lib.mime_type import mime_type

annotation_properties={'comment':('author_name','author_link','author_email'),
                    'trackback':('blog_name','url','title')}
class resource_getter:
    '''Used within the wiki formatters to embed wiki content from other pages '''
    def __init__(self,key):
        self.rr=resource(key)
        self.key=key # for debugging get_html :-)
    def exists(self):
        if self.rr.special: return 1
        return self.rr.exists()
    def get_html(self):
        return self.rr.get()['content']
    
                    
class resource:
    ''' 
    This class represents the semantics associated with an entry
    in the leonardo file system. Essentially such an object is one     
      a) a document under wiki control, 
      b) an uploaded document, or
      c) a special resource which has the semantics of something that
      can be treated as if it is from the LFS.  
    In the first two cases there may or many not be comments and trackbacks 
    associated with he resource. 
    It may be possible that there is an atom version of the content.
    
    ... By the way, this is composition not inheritance. By design '''
    
    def __init__(self,key,instance=None):
        ''' Instantiate pointer to the lfs object '''
        #we get an instance generally if it's a comment or tracback request ...
        
        if instance is None: instance=g.lfs.get(key)
        self.leof=instance 
        self.content=self.leof.get_content()
        self.content_type=self.leof.get_content_type()
        
        self.key=key
        self.path=request.environ['PATH_INFO']
 
        # See if this is a special resource (i.e. something with the
        # semantics of a reosurce from the lfs, but actually not ... 
        
        kkey=key
        if kkey.startswith('category'): kkey='category'
        specialResources={'calendar':self._calendar,
                          'category':self._category}
        
        if kkey in specialResources:
            self.special=specialResources[kkey]
        else:
            self.special=0        
        
    def exists(self):
        return self.leof.exists()
    
    def get(self):
        ''' Return the primary content of the lfs object as a dictionary'''
        if self.special:return self.special()
        if self.content==None: return None
        title=self.get_metadata('page_title')
        if self.content_type.startswith('wiki'):
            self.html=self._format(self.content,self.content_type)
            r={'content_type':'text/html','content':self.html,'title':title}
            r['allow_trackbacks']=self.get_metadata('allow_trackbacks')
            r['allow_comments']=self.get_metadata('allow_comments')
            r['categories']=self.get_metadata('categories')
        else:
            ''' This is something which has been uploaded ...'''
            ct=mime_type(self.content_type)
            r={'content':self.content,'content_type':ct,'title':title}
            r['categories']=[]
        r['author']=self.get_metadata('author')
        r['creation_time']=self.get_metadata('creation_time')
        r['last_modified']=self.leof.get_lastmod()
        return r
            
    def get_metadata(self,arg):
        ''' Return attribute metadata for arg '''
        if self.special: return self.key
        return self.leof.get_property(arg)
    
    def get_annotations(self,atype='comment'):
        ''' Return annotations (default is comments, can call with 'trackback' as
        an optional argument, or 'all' to get all '''
        if atype=='all': 
            do=['commment','trackback']
        else: do = [atype]
        annotations=[]
        for i in do:
            leoan=self.leof.enclosures(i)
            for a in leoan:
                rr=resource('ignore',instance=a)
                r=rr.get()
                for p in annotation_properties[i]:
                    r[p]=rr.get_metadata(p)
                r['index']=a.index
                annotations.append(r)
        return annotations
                
                
    def _format(self,content,content_type): 
        '''parse wiki page format and produce html '''
        formatters = {
            "wiki04": wiki04.WikiFormatter(g.home_href),
            "wikiBNL": wikiBNL.WikiFormatter(g.home_href),
            "xhtml": xhtml.XHTMLFormatter(g.home_href),
        }
        if content_type not in formatters:
            return content
        
        return formatters[content_type].format(content,self.leof,resource_getter)

            
    ##
    ## The following methods wrap calls to produce the html required to put up 
    ## links to interesting leonardo actions (or to html which doesn't come from
    ## the LFS).
    ##
            
    def _category(self):
        ''' Sets things up so that a get returns a category listing page '''
        category=self.key[9:]
        self.category='Category %s'%category
        keylist=[]
        for page in g.lfs.find_property("categories").get(category, []):
            #ok, I'm not comfortable with how this will pan out in more complicated deployments ...
            draft=page.startswith(g.draft_prefix.strip('/'))
            #
            if not draft or c.loginStatus:
                rr=resource(page)
                title=rr.get_metadata("page_title") or resource
                if draft: title='Draft:'+title
                lastmod=rr.get_metadata('lastmod')
                keylist.append((lastmod,title,page))
        keylist.sort()
        self.content='<ul>'
        for item in keylist:
            self.content += """<li><a href="%s">%s</a></li>""" % (item[2],item[1])
        self.content+='</ul>'
        return {'content':self.content,'content_type':'text/html','title':item[1]}  

    
    def _calendar(self):
        bc=BC.BlogCalendar(self.path)
        self.content=bc.html
        return {'content':self.content,'content_type':'text/html','title':''}
    
